package jia.editor;

import jia.core.Compass;
import jia.core.Module;
import jia.core.Space;
import jia.core.Wall;
import org.apache.log4j.Logger;

import javax.vecmath.Vector2d;
import java.awt.event.MouseEvent;

// ====================================================
/**
 * @author Alec Lanter
 */
public class ModuleEditorPanelController{
    private static final Logger log = Logger.getLogger(ModuleEditorPanelController.class);
    private static final int STATE_WALL = 1;
    private static final int STATE_ZONE = 2;
    private static final int STATE_BACKDROP = 4;
    private static final int STATE_EVENT = 8;
    private ModuleEditorPanel editPanel;
    private int currentState = STATE_WALL;
    private String imageName;
    private String imageParser = "jia.core.graphics.FirstPersonWallImageParser";
    private String backdropName;
    private ScreenLocationData lastEdited;
    private int dragButton;
    
    // ====================================================
    /**
     */
    private ModuleEditorPanelController(){
        // GNDN
    }
    
    // ====================================================
    /**
     * @param panel
     */
    public ModuleEditorPanelController(ModuleEditorPanel panel){
        editPanel = panel;
    }
    
    // ====================================================
    /**
     * @param evt
     */
    public void handleMouseClick(MouseEvent evt){
        ScreenLocationData data = editPanel.getScreenData(evt.getX(), evt.getY());
        lastEdited = data;
        if(data == null) {
            return;
        }
        switch(currentState) {
            case STATE_WALL:
                handleWallEdit(evt, data);
                break;
            case STATE_BACKDROP:
                editBackdrop(data);
                break;
            case STATE_EVENT:
                editEvent(data);
                break;
            case STATE_ZONE:
                editZone(data);
                break;
        }
    }
    
    //====================================================
    /**
     * @param evt
     * @param data
     */
    private void handleWallEdit(MouseEvent evt, ScreenLocationData data){
        if(data.getClosestWall() == null) {
            return;
        }
        int button = evt.getButton();
        if(button == 0) {
            button = dragButton;
        }
        if(button == MouseEvent.BUTTON1) {
            addWall(data);
        } else if(button == MouseEvent.BUTTON3) {
            removeWall(data);
        }
    }
    
    // ====================================================
    /**
     * @param data
     */
    private void addWall(ScreenLocationData data){
        Vector2d loc = data.getModuleLoc();
        
        // Add the specified wall to the clicked space...
        createWall(loc, data.getClosestWall());
        
        // And to the other side of the selected wall...
        Compass aboutFace = Compass.add(data.getClosestWall(), Compass.SOUTH);
        switch(aboutFace.getDirectionalValue()) {
            case Compass.NORTH_VAL:
                loc.y++;
                break;
            case Compass.SOUTH_VAL:
                loc.y--;
                break;
            case Compass.EAST_VAL:
                loc.x--;
                break;
            case Compass.WEST_VAL:
                loc.x++;
                break;
        }
        createWall(loc, aboutFace);
        editPanel.repaint();
    }
    
    //====================================================
    /**
     * @param loc
     * @param facing
     */
    private void createWall(Vector2d loc, Compass facing){
        Module module = editPanel.getGameState().getPlayerState().getCurrentModule();
        Space space = module.getSpace(loc);
        if(space == null) {
            space = new Space();
            space.setBackdropImageName(backdropName);
            module.setSpace(loc, space);
        }
        Wall wall = space.getWall(facing);
        if(wall == null) {
            wall = new Wall(imageName, imageParser, facing);
            space.addWall(wall);
        }
    }
    
    //====================================================
    /**
     * @param loc
     * @param facing
     */
    private void deleteWall(Vector2d loc, Compass facing){
        Module module = editPanel.getGameState().getPlayerState().getCurrentModule();
        Space space = module.getSpace(loc);
        if(space != null) {
            Wall wall = space.getWall(facing);
            if(wall != null) {
                space.removeWall(wall);
            }
        }
    }
    
    //====================================================
    /**
     * @param data
     */
    private void removeWall(ScreenLocationData data){
        Vector2d loc = data.getModuleLoc();
        
        // Delete the selected wall
        deleteWall(loc, data.getClosestWall());
        
        // And the opposite wall in the adjoining space
        Compass aboutFace = Compass.add(data.getClosestWall(), Compass.SOUTH);
        switch(aboutFace.getDirectionalValue()) {
            case Compass.NORTH_VAL:
                loc.y++;
                break;
            case Compass.SOUTH_VAL:
                loc.y--;
                break;
            case Compass.EAST_VAL:
                loc.x--;
                break;
            case Compass.WEST_VAL:
                loc.x++;
                break;
        }
        deleteWall(loc, aboutFace);
        editPanel.repaint();
    }
    
    // ====================================================
    /**
     * @param data
     */
    private void editBackdrop(ScreenLocationData data){
    }
    
    // ====================================================
    /**
     * @param data
     */
    private void editEvent(ScreenLocationData data){
    }
    
    // ====================================================
    /**
     * @param data
     */
    private void editZone(ScreenLocationData data){
    }
    
    // ====================================================
    /**
     * @return Returns the backdropName.
     */
    public String getBackdropName(){
        return backdropName;
    }
    
    // ====================================================
    /**
     * @param backdropName The backdropName to set.
     */
    public void setBackdropName(String backdropName){
        this.backdropName = backdropName;
    }
    
    // ====================================================
    /**
     * @return Returns the currentState.
     */
    public int getCurrentState(){
        return currentState;
    }
    
    // ====================================================
    /**
     * @param currentState The currentState to set.
     */
    public void setCurrentState(int currentState){
        this.currentState = currentState;
    }
    
    // ====================================================
    /**
     * @return Returns the imageName.
     */
    public String getImageName(){
        return imageName;
    }
    
    // ====================================================
    /**
     * @param imageName The imageName to set.
     */
    public void setImageName(String imageName){
        this.imageName = imageName;
    }
    
    // ====================================================
    /**
     * @return Returns the imageParser.
     */
    public String getImageParser(){
        return imageParser;
    }
    
    // ====================================================
    /**
     * @param imageParser The imageParser to set.
     */
    public void setImageParser(String imageParser){
        this.imageParser = imageParser;
    }
    
    //====================================================
    /**
     * @param evt
     */
    public void handleMouseDrag(MouseEvent evt){
        ScreenLocationData data = editPanel.getScreenData(evt.getX(), evt.getY());
        if(!data.equals(lastEdited)) {
            handleMouseClick(evt);
        }
    }
    
    //====================================================
    /**
     * @return Returns the mouseButtonMask.
     */
    public int getDragButton(){
        return dragButton;
    }
    
    //====================================================
    /**
     * @param dragButton The mouseButtonMask to set.
     */
    public void setDragButton(int dragButton){
        this.dragButton = dragButton;
    }
}
